﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Orchard.Model;
using System.Drawing.Imaging;
using Orchard.View;

namespace Orchard.Controller
{
    public partial class TreeControl : UserControl
    {

        Tree tree; //Store all the information about this tree.
        Bitmap leafCanopy; //An image of just the leaves for the tree.
        Bitmap treeTrunk;
        Bitmap shadowCanopy; //A shadow image of just the leaves for this tree.
        
        int oldNumRings;
        int numRings;
        int trunkWidth;
        int trunkHeight;
        int zeroCheck;

        int deadTrunkWidth;
        int deadTrunkHeight;
        
        //Loaction of the top of the tree;
        int treeTopX;
        int treeTopY;

        //Location adjustments.
        int placeTreeX;
        int placeTreeY;
        int placeLeavesX;
        int placeLeavesY;

        //Slight adjustments.
        int adjustTreeY;
        int adjustTreeX;
        int adjustLeafY;

        //Grass stuff.
        int grassHeight = 50;

        //Draw a stump?
        bool drawStump;

        //Leaf Images.
        Image smallBrownNWCarobLeafNormal;
        Image smallBrownNWCarobLeafXFlip;
        Image smallBrownNWCarobLeafYFlip;
        Image smallBrownNWCarobLeafXYFlip;

        Image smallGreenNECarobLeafNormal;
        Image smallGreenNECarobLeafXFlip;
        Image smallGreenNECarobLeafYFlip;
        Image smallGreenNECarobLeafXYFlip;

        Image mediumGreenSWCarobLeafNormal;
        Image mediumGreenSWCarobLeafXFlip;
        Image mediumGreenSWCarobLeafYFlip;
        Image mediumGreenSWCarobLeafXYFlip;

        Image largeGreenNECarobLeafNormal;
        Image largeGreenNECarobLeafXFlip;
        Image largeGreenNECarobLeafYFlip;
        Image largeGreenNECarobLeafXYFlip;


        public TreeControl()
        {

            InitializeComponent();

            //Create all the leaf images and do the needed image rotations.
            smallBrownNWCarobLeafNormal = new Bitmap(Properties.Resources.smallBrownNWCarobLeaf);
            smallBrownNWCarobLeafXFlip = new Bitmap(Properties.Resources.smallBrownNWCarobLeaf);
            smallBrownNWCarobLeafXFlip.RotateFlip(RotateFlipType.RotateNoneFlipX);
            smallBrownNWCarobLeafYFlip = new Bitmap(Properties.Resources.smallBrownNWCarobLeaf);
            smallBrownNWCarobLeafYFlip.RotateFlip(RotateFlipType.RotateNoneFlipY);
            smallBrownNWCarobLeafXYFlip = new Bitmap(Properties.Resources.smallBrownNWCarobLeaf);
            smallBrownNWCarobLeafXYFlip.RotateFlip(RotateFlipType.RotateNoneFlipXY);

            smallGreenNECarobLeafNormal = new Bitmap(Properties.Resources.smallGreenNECarobLeaf);
            smallGreenNECarobLeafXFlip = new Bitmap(Properties.Resources.smallGreenNECarobLeaf);
            smallGreenNECarobLeafXFlip.RotateFlip(RotateFlipType.RotateNoneFlipX);
            smallGreenNECarobLeafYFlip = new Bitmap(Properties.Resources.smallGreenNECarobLeaf);
            smallGreenNECarobLeafYFlip.RotateFlip(RotateFlipType.RotateNoneFlipY);
            smallGreenNECarobLeafXYFlip = new Bitmap(Properties.Resources.smallGreenNECarobLeaf);
            smallGreenNECarobLeafXYFlip.RotateFlip(RotateFlipType.RotateNoneFlipXY);

            mediumGreenSWCarobLeafNormal = new Bitmap(Properties.Resources.mediumGreenSWCarobLeaf);
            mediumGreenSWCarobLeafXFlip = new Bitmap(Properties.Resources.mediumGreenSWCarobLeaf);
            mediumGreenSWCarobLeafXFlip.RotateFlip(RotateFlipType.RotateNoneFlipX);
            mediumGreenSWCarobLeafYFlip = new Bitmap(Properties.Resources.mediumGreenSWCarobLeaf);
            mediumGreenSWCarobLeafYFlip.RotateFlip(RotateFlipType.RotateNoneFlipY);
            mediumGreenSWCarobLeafXYFlip = new Bitmap(Properties.Resources.mediumGreenSWCarobLeaf);
            mediumGreenSWCarobLeafXYFlip.RotateFlip(RotateFlipType.RotateNoneFlipXY);

            largeGreenNECarobLeafNormal = new Bitmap(Properties.Resources.largeGreenNECarobLeaf);
            largeGreenNECarobLeafXFlip = new Bitmap(Properties.Resources.largeGreenNECarobLeaf);
            largeGreenNECarobLeafXFlip.RotateFlip(RotateFlipType.RotateNoneFlipX);
            largeGreenNECarobLeafYFlip = new Bitmap(Properties.Resources.largeGreenNECarobLeaf);
            largeGreenNECarobLeafYFlip.RotateFlip(RotateFlipType.RotateNoneFlipY);
            largeGreenNECarobLeafXYFlip = new Bitmap(Properties.Resources.largeGreenNECarobLeaf);
            largeGreenNECarobLeafXYFlip.RotateFlip(RotateFlipType.RotateNoneFlipXY);
            
            //Create the "canvas" for the leaves and the trees.
            tree = new Tree(TreeTypeEnum.ExerciseTree);
            leafCanopy = new Bitmap(this.Width,this.Height);
            treeTrunk = new Bitmap(this.Width, this.Height);
            shadowCanopy = new Bitmap(this.Width, this.Height);
            zeroCheck = 0;
        }

        public Tree Tree
        {
            get { return tree; }
            set { tree = value; }
        }

        private void TreeControl_Paint(object sender, PaintEventArgs e)
        {
            //Store information about the old tree.
            if (this.tree.Rings.Count() == 0)
            {
                oldNumRings = 0;
                numRings = 0;
                deadTrunkHeight = 40;
                deadTrunkWidth = 100;
            }

            //The program is no longer on the first run.
            else
            {
                zeroCheck += this.tree.Rings.Count();
                numRings = this.tree.Rings.Count();
            }

            //It program is on its first run, don't draw the stump.
            if (zeroCheck == 0)
            {
                drawStump = false;
                trunkWidth = (int)Math.Sqrt(1 * 1000);
                trunkHeight = (int)Math.Sqrt(1 * 2000);
                Console.WriteLine("in here");
            }

            //Not the first run, draw the stump.
            else
            {
                numRings = this.tree.Rings.Count();
                trunkWidth = (int)Math.Sqrt(numRings * 1000);
                trunkHeight = (int)Math.Sqrt(numRings * 2000);
                drawStump = true;
            }

            
            drawTreeTrunk();
            addLeaves();
            
            e.Graphics.DrawImage(treeTrunk,0,0);
            e.Graphics.DrawImage(leafCanopy,placeLeavesX,placeLeavesY);     
        }



        private void drawTreeTrunk()
        {
            //Create an image of the new trunk.
            Image newTreeTrunk;
            treeTrunk = new Bitmap(this.Width, this.Height);
            
            using (Graphics gfx = Graphics.FromImage(treeTrunk))
            {

                //Different seeds for the different trees.

                Image grass = new Bitmap(Properties.Resources.bradgrass, this.Width + 20, 50);
                gfx.DrawImage(grass, 0, this.Height - 50);

                //Days 0-3
                if (numRings == 0 && drawStump)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.largeStump, deadTrunkWidth, deadTrunkHeight);
                    adjustTreeY = 30;
                    adjustTreeX = 0;
                }

                else if (numRings <= 3)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize0, trunkWidth , trunkHeight);
                    adjustTreeY = -2;
                    adjustLeafY = 2;
                    adjustTreeX = 0;
                }
                //Days 4 - 9
                else if (numRings >= 4 && numRings <= 9)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize1, trunkWidth, trunkHeight);
                    adjustTreeY = -3;
                    adjustLeafY = 5;
                    adjustTreeX = 15;
                }
                //Days 10 - 15 
                else if (numRings >= 10 && numRings <= 15)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize2, trunkWidth, trunkHeight);
                    adjustTreeY = -8;
                    adjustLeafY = 20;
                    adjustTreeX = 10;

                }
                //Days 16 - 22
                else if (numRings >= 16 && numRings <= 22)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize3, trunkWidth, trunkHeight);
                    adjustTreeY = -8;
                    adjustTreeX = 10;
                    adjustLeafY = 30;
                }
                //Days 23 - 30
                else if (numRings >= 23 && numRings <= 30)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize4, trunkWidth, trunkHeight);
                    adjustTreeY = -8;
                    adjustLeafY = 47;
                    adjustTreeX = 0;
                }
                //Days 31 - 37
                else if (numRings >= 31 && numRings <= 37)
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize5, trunkWidth, trunkHeight);
                    adjustTreeY = -10;
                    adjustLeafY = 60;
                    adjustTreeX = 0;
                }
                //Days 38 - 45
                else
                {
                    newTreeTrunk = new Bitmap(Properties.Resources.trunkSize6, trunkWidth, trunkHeight);
                    adjustLeafY = 80;
                    adjustTreeY = -20;
                    adjustTreeX = 0;
                }

                placeTreeY = this.Height - trunkHeight - grassHeight - adjustTreeY;
                placeTreeX = (this.Width / 2) - (trunkWidth / 2) + adjustTreeX;


                gfx.DrawImage(newTreeTrunk, placeTreeX, placeTreeY);

            }
            
       }

    
        private void addLeaves()
        {
            if (numRings == 0 && zeroCheck != 0)
                leafCanopy = new Bitmap(this.Width, this.Height);

            if (oldNumRings == numRings && zeroCheck != 0) return;
            Image leafNormal;
            Image leafXFlip;
            Image leafYFlip;
            Image leafXYFlip;

            //int oldNumLeaves = (int)Math.Ceiling(Math.Pow(oldNumRings, 2) / 4);
            //int newNumLeaves = (int)Math.Ceiling((double)(int)Math.Ceiling(Math.Pow((numRings-oldNumRings), 2)) / 2);
            int newNumLeaves = (int)Math.Pow((double)(numRings - oldNumRings + 1), 1.7) * 2;
            Console.WriteLine(this.Name, " ", newNumLeaves);
            int numNewRings = numRings - oldNumRings;
            //There is a new "old" number of rings.
            oldNumRings = numRings;

            if (tree.getNewTree() == true)
            {
                newNumLeaves = 1;
            }
            //Don't draw any leaves.
            else if (numNewRings == 0)
                return;
            //Clear the leaves.
            if (numNewRings < 0)
            {
                leafCanopy = new Bitmap(this.Width, this.Height);
            }
            //Add all the new leaves to the image.
            
            //Various leaf variables.
            int radiusCanopy = trunkWidth / 2;

            if (zeroCheck == 0)
                radiusCanopy = 20;

            int sizeVariant = 7;
            int leafSizeX = 15;
            int leafSizeY = 15;

            //Create the sized images.
            Image sizedTreeLeaf1 = new Bitmap(Properties.Resources.leafOne, leafSizeX, leafSizeY);
            Image sizedTreeLeaf2 = new Bitmap(Properties.Resources.leafOne, leafSizeX, leafSizeY);
            Image sizedTreeLeaf3 = new Bitmap(Properties.Resources.leafOne, leafSizeX, leafSizeY);
            Image sizedTreeLeaf4 = new Bitmap(Properties.Resources.leafOne, leafSizeX, leafSizeY);

            //Different seeds for the different trees.
            int ranNumSeed = 0;
            if (this.Name == "exerciseTreeControl") 
                ranNumSeed = 1;
            else if (this.Name == "learningTreeControl") 
                ranNumSeed = 2;
            else if (this.Name == "productivityTreeControl")
                ranNumSeed = 3;

            //Declare coordinate variables and the random number generator.
            Random randNum = new Random(ranNumSeed);
            int xCoord = 0;
            int yCoord = 0;
            int radianCoord = 0;
            int radiusSize = 0;
            int xLeafSizeVariant = 0;
            int yLeafSizeVariant = 0;

            Console.WriteLine("Number of new leaves:");
            Console.WriteLine(newNumLeaves);

            //Draw all the leaves onto the old image.
            using (Graphics gfx = Graphics.FromImage(leafCanopy))
            {
                for (int i = 0; i < newNumLeaves; i++)
                {
                    //Get a random degree and radius size, calculate the x,y coords and draw.
                    radianCoord = randNum.Next(0, 360);
                    radiusSize = randNum.Next(0, radiusCanopy);

                    if (i % 2 == 0)
                    {
                        leafNormal = this.mediumGreenSWCarobLeafNormal;
                        leafXFlip = this.mediumGreenSWCarobLeafXFlip;
                        leafYFlip = this.mediumGreenSWCarobLeafYFlip;
                        leafXYFlip = this.mediumGreenSWCarobLeafXYFlip;
                    }
                    else if (i % 7 == 0)
                    {
                        leafNormal = this.smallGreenNECarobLeafNormal;
                        leafXFlip = this.smallGreenNECarobLeafXFlip;
                        leafYFlip = this.smallGreenNECarobLeafYFlip;
                        leafXYFlip = this.smallGreenNECarobLeafXYFlip;
                    }
                    else if (i % 37 == 0)
                    {
                        leafNormal = this.smallBrownNWCarobLeafNormal;
                        leafXFlip = this.smallBrownNWCarobLeafXFlip;
                        leafYFlip = this.smallBrownNWCarobLeafYFlip;
                        leafXYFlip = this.smallBrownNWCarobLeafXYFlip;
                    }
                    else
                    {
                        leafNormal = this.largeGreenNECarobLeafNormal;
                        leafXFlip = this.largeGreenNECarobLeafXFlip;
                        leafYFlip = this.largeGreenNECarobLeafYFlip;
                        leafXYFlip = this.largeGreenNECarobLeafXYFlip;
                    }

                    //Use RNG, resize the images.
                    xLeafSizeVariant = randNum.Next(-sizeVariant, sizeVariant);
                    yLeafSizeVariant = randNum.Next(-sizeVariant, sizeVariant);
                    sizedTreeLeaf1 = new Bitmap(leafNormal, leafSizeX + xLeafSizeVariant, leafSizeY + yLeafSizeVariant);
                    sizedTreeLeaf2 = new Bitmap(leafXFlip, leafSizeX + xLeafSizeVariant, leafSizeY + yLeafSizeVariant);
                    sizedTreeLeaf3 = new Bitmap(leafYFlip, leafSizeX + xLeafSizeVariant, leafSizeY + yLeafSizeVariant);
                    sizedTreeLeaf4 = new Bitmap(leafXYFlip, leafSizeX + xLeafSizeVariant, leafSizeY + yLeafSizeVariant);

                    //Get coordinates and place the leaves.
                    xCoord = (int)((this.Width / 2) + radiusSize * Math.Cos(radianCoord * (Math.PI / 180)));
                    yCoord = (int)((this.Height / 2)  + radiusSize * Math.Sin(radianCoord * (Math.PI / 180)));
                    if ((xCoord % 2 == 0) && (yCoord % 2 != 0))
                    {
                        //Leaf 1
                        gfx.DrawImage(sizedTreeLeaf1, xCoord, yCoord);
                    }
                    else if ((xCoord % 2 == 0) && (yCoord % 2 == 0))
                    {
                        //Leaf 2
                        gfx.DrawImage(sizedTreeLeaf2, xCoord, yCoord);
                    }
                    else if ((xCoord % 2 != 0) && (yCoord % 2 != 0))
                    {
                        //Leaf 3
                        gfx.DrawImage(sizedTreeLeaf4, xCoord, yCoord);
                    }
                    else if ((xCoord % 2 != 0) && (yCoord % 2 == 0))
                    {
                        //Leaf 4
                        gfx.DrawImage(sizedTreeLeaf3, xCoord, yCoord);
                    }
                    else
                    {
                        //Who knows how you get in here (if you even do), but lets draw it anyway.
                        gfx.DrawImage(sizedTreeLeaf1, xCoord, yCoord);
                    }
                    placeLeavesX = 0;
                    placeLeavesY = (this.Height / 2) - (this.Height - (this.Height - grassHeight - adjustTreeY - trunkHeight)) + adjustLeafY;
                }
            }
        }

        private void TreeControl_MouseEnter(object sender, EventArgs e)
        {
            BackgroundImage = Orchard.Properties.Resources.TreeShadow;
        }

        private void TreeControl_MouseLeave(object sender, EventArgs e)
        {
            BackgroundImage = null;
        }
    }
}